home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 5 / QRZ Ham Radio Callsign Database - Volume 5.iso / files / amiga / csrc720j.lzh / ser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-05  |  10.7 KB  |  365 lines

  1. /* ser.c */
  2.  
  3. /* heavily borrowed from my program to control the ic-735 via rs-232 */
  4. #include <exec/types.h>
  5. #include <exec/exec.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/intuitionbase.h>
  8. #include <graphics/text.h>
  9. #include <devices/serial.h>
  10. #include <ctype.h>
  11. #include <libraries/dos.h>
  12. #include "mb.h"
  13. #include "amiga.h"
  14. extern short debug;
  15. extern char *speed;
  16. extern struct Window *mywindow;
  17. extern long keybit,readbit,windbit;
  18. extern char tmpstr[],optflags[];
  19. extern short done_flag;
  20. /*   */
  21. long getbits;
  22. ULONG class;
  23. USHORT code;
  24.  
  25. /* msg structure for GetMsg() */
  26. extern struct IntuiMessage *NewMessage;
  27.  
  28. /* declarations for the serial stuff */
  29. struct IOExtSer *Ser_Read;
  30. unsigned char rs_in[2];
  31. struct IOExtSer *Ser_Write;
  32. unsigned char rs_out[2];
  33. int serflags;
  34. short tapr_flag = 0;    /* Using tapr upgrade? */
  35. long BaudRate = 9600L;
  36.  
  37. /* defaults to "serial.device" but user can change it if they have a
  38.    multi-serial card
  39. */
  40. extern UBYTE *ser_dev_name;
  41. extern long unit;          /* defaults to zero, but can be changed */
  42. initser()
  43. {
  44.    long error;
  45.    if(ser_dev_name == 0L)ser_dev_name = (UBYTE *)SERIALNAME;
  46.    Ser_Read = (struct IOExtSer *)AllocMem
  47.                   ((long)sizeof(*Ser_Read),
  48.                    (long)MEMF_PUBLIC|MEMF_CLEAR);
  49.    serflags = Ser_Read->io_SerFlags =
  50.                     SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
  51.    Ser_Read->IOSer.io_Message.mn_ReplyPort =  CreatePort(0L,0L);
  52.    if(OpenDevice(ser_dev_name,unit,(struct IORequest *)Ser_Read,0L))   {
  53.       puts("Cant open Read device\n");
  54.       DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
  55.       FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
  56.       return(1);
  57.    }
  58.    Ser_Read->IOSer.io_Command = CMD_READ;
  59.    Ser_Read->IOSer.io_Length = 1L;
  60.    Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
  61.  
  62.    Ser_Write = (struct IOExtSer *)AllocMem
  63.                              ((long)sizeof(*Ser_Write),
  64.                               (long)MEMF_PUBLIC|MEMF_CLEAR);
  65.    Ser_Write->io_SerFlags = SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
  66.    Ser_Write->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
  67.    if(OpenDevice(ser_dev_name,unit,(struct IORequest *)Ser_Write,0L))   {
  68.       puts("Cant open Write device\n");
  69. getout:
  70.       CloseDevice((struct IORequest *)Ser_Read);
  71.       DeletePort(Ser_Write->IOSer.io_Message.mn_ReplyPort);
  72.       FreeMem(Ser_Write,(long)sizeof(*Ser_Write));
  73.       DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
  74.       FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
  75.       return(1);
  76.    }
  77.    Ser_Read->io_TermArray.TermArray0 = 0x0L;
  78.    Ser_Read->io_TermArray.TermArray1 = 0x0L;
  79.    Ser_Write->IOSer.io_Command = CMD_WRITE;
  80.    Ser_Write->IOSer.io_Length = 1L;
  81.    Ser_Write->IOSer.io_Data = (APTR) &rs_out[0];
  82.    Ser_Read->IOSer.io_Command = SDCMD_SETPARAMS;
  83.    Ser_Read->io_SerFlags =  SERF_SHARED | SERF_XDISABLED | SERF_7WIRE;
  84.    if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
  85.       sprintf(tmpstr,"error 0 #%ld from setcommand in seric.c\n",error);
  86.       ttputs(tmpstr);
  87.       goto getout;
  88.    }
  89.    /* Set the break time which is required if the TNC is used in transparent
  90.       mode. It is probably only necessary to do this once for Ser_Read but
  91.       I do Ser_Write as well just in case. The default appears to be 
  92.       250000.
  93.    */
  94.    Ser_Read->io_BrkTime = 300000L;
  95.    Ser_Write->io_BrkTime = 300000L;
  96.    Ser_Read->io_Baud = BaudRate;
  97.    if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
  98.       sprintf(tmpstr,"error 1 #%ld from setcommand in seric.c\n",error);
  99.       ttputs(tmpstr);
  100.       goto getout;
  101.    }
  102.    Ser_Write->IOSer.io_Command = SDCMD_SETPARAMS;
  103.    if((error = DoIO((struct IORequest *)Ser_Write)) != 0) {
  104.       sprintf(tmpstr,"error W #%ld from setcommand in seric.c\n",error);
  105.       ttputs(tmpstr);
  106.       goto getout;
  107.    }
  108.    Ser_Read->io_ReadLen = 8;
  109.    Ser_Read->io_WriteLen = 8;
  110.    if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
  111.       sprintf(tmpstr,"error 2 #%ld from setcommand in seric.c\n",error);
  112.       ttputs(tmpstr);
  113.       goto getout;
  114.    }
  115.    Ser_Read->io_RBufLen = 4096L;
  116.    if((error = DoIO((struct IORequest *)Ser_Read)) != 0) {
  117.       sprintf(tmpstr,"error 3 #%ld from setcommand in seric.c\n",error);
  118.       ttputs(tmpstr);
  119.       goto getout;
  120.    }
  121.    Ser_Read->IOSer.io_Command = CMD_READ;
  122.  
  123.    BeginIO((struct IORequest *)Ser_Read);
  124.  
  125.    readbit = (1L << Ser_Read->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
  126.    return(0);
  127. }
  128.  
  129. cleanser()
  130. {
  131.    AbortIO((struct IORequest *)Ser_Read);
  132.    AbortIO((struct IORequest *)Ser_Write);
  133.    CloseDevice((struct IORequest *)Ser_Read);
  134.    CloseDevice((struct IORequest *)Ser_Write);
  135.    DeletePort(Ser_Write->IOSer.io_Message.mn_ReplyPort);
  136.    FreeMem(Ser_Write,(long)sizeof(*Ser_Write));
  137.    DeletePort(Ser_Read->IOSer.io_Message.mn_ReplyPort);
  138.    FreeMem(Ser_Read,(long)sizeof(*Ser_Read));
  139. }
  140.  
  141. /*
  142.    Read one char from the serial port.
  143.    If rflag is non-null then don't start the next read IO.
  144.    This is only used in YAPP and is turned off when it is done.
  145. */
  146. short rflag = 0;
  147. extern long serfirst;
  148. unsigned char rdchar()
  149. {
  150.    unsigned char c;
  151.    long waitbits;
  152.  
  153.    waitbits = windbit | readbit;
  154.    /* There might already be an unread char at the serial port */
  155.    serfirst = 0L;
  156.    if(CheckIO((struct IORequest *)Ser_Read)) {
  157.       Wait(readbit);
  158.       serfirst |= readbit;
  159.    }
  160.    while(1)  {
  161.       if(serfirst) {
  162.          getbits = serfirst;
  163.          serfirst = 0L;
  164.       }
  165.       else {
  166.          getbits = Wait(waitbits);
  167.       }
  168.       if(windbit & getbits) {
  169.          while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  170.             class = NewMessage->Class;
  171.             code = NewMessage->Code;
  172.             switch( class ) {
  173.             case CLOSEWINDOW:
  174.                if(done_flag)done(1);
  175.                break;
  176.             default:
  177.                ReplyMsg((struct Message *) NewMessage );
  178.             }   /* end of switch (class) */
  179.          }
  180.       }
  181.       if(readbit & getbits) {
  182.          WaitIO((struct IORequest *)Ser_Read);
  183.          c = rs_in[0];
  184.          if(tapr_flag)c &= 0177;
  185.          Ser_Read->IOSer.io_Command = CMD_READ;
  186.          Ser_Read->IOSer.io_Length = 1L;
  187.          Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
  188.          if(!rflag)BeginIO((struct IORequest *)Ser_Read);
  189.          return(c);
  190.       }
  191.    }
  192. }
  193. /* This flag is used to allow the program to detect when a user has
  194.    sent data while we are sending them info. This will be interpreted
  195.    as an interrupt.
  196.    The code looking for an interrupt must clear the flag first and then
  197.    test it where appropriate.
  198. */
  199. /* send character to the serial port */
  200. schar(ch)
  201. int ch;
  202. {
  203.  
  204.    Ser_Write->IOSer.io_Command = CMD_WRITE;
  205.    Ser_Write->IOSer.io_Length = 1L;
  206.    Ser_Write->IOSer.io_Data = (APTR) &rs_out[0];
  207.    rs_out[0] = ch;
  208.    DoIO((struct IORequest *)Ser_Write);
  209. }
  210.  
  211. /* Allows program to Check Carrier Detect and/or DSR */
  212. getserstat()
  213. {
  214.    Ser_Write->IOSer.io_Command = SDCMD_QUERY;
  215.    DoIO((struct IORequest *)Ser_Write);
  216.    return(Ser_Write->io_Status);
  217. }
  218.  
  219. /* send the command string in s */
  220. sends(s)
  221. unsigned char *s;
  222. {
  223.    register unsigned char *p;
  224.    register short i;
  225.  
  226.    i = 0;
  227.    p = s;
  228.    /* Count the number of chars in the string */
  229.    while(*p++)i++;
  230.    if(i == 0)return;
  231.    Ser_Write->IOSer.io_Command = CMD_WRITE;
  232.    Ser_Write->IOSer.io_Length = i;
  233.    Ser_Write->IOSer.io_Data = (APTR) s;
  234.    DoIO((struct IORequest *)Ser_Write);
  235. }
  236. extern short block_cancel;
  237. sendblock(s,l)
  238. unsigned char *s;
  239. int l;
  240. {
  241.    register char ch;
  242.    extern unsigned char ichar;
  243.    extern struct IOStdReq *Con_Read;
  244.  
  245.    Ser_Write->IOSer.io_Command = CMD_WRITE;
  246.    Ser_Write->IOSer.io_Length = l;
  247.    Ser_Write->IOSer.io_Data = (APTR) s;
  248.    DoIO((struct IORequest *)Ser_Write);
  249.    if(CheckIO((struct IORequest *)Con_Read)) {
  250.       Wait(keybit);
  251.       WaitIO((struct IORequest *)Con_Read);
  252.       ch = ichar;
  253.       Con_Read->io_Data = (APTR)&ichar;
  254.       Con_Read->io_Command = CMD_READ;
  255.       Con_Read->io_Length = 1;
  256.       SendIO((struct IORequest *)Con_Read);
  257.       if(ch == '\033') {
  258.          ttputs("sendblock\n");
  259.       }
  260.       if(ch == achar) {
  261.          block_cancel = 1;
  262.          port->mode = forced;
  263.          AbortIO((struct IORequest *)Ser_Read);
  264.          restart();
  265.          return(1);
  266.       }
  267.    }
  268.    return(0);
  269. }
  270. breakport()
  271. {
  272.    Ser_Write->IOSer.io_Command = SDCMD_BREAK;
  273.    DoIO((struct IORequest *)Ser_Write);
  274. }
  275. rdblock(p,l)
  276. char *p;
  277. int l;
  278. {
  279.    register int i;
  280.  
  281.    /* Negative length indicates read a null-terminated string of maximum
  282.       length -l including the null.
  283.    */
  284.    if(l < 0) {
  285.  
  286.       /* Looking for a null-terminated string is not supported by the
  287.          ibmser.device for the GoldenGate II card and, as Dan Babcock
  288.          who wrote ibmser.device has told me, it is an inherently
  289.          unreliable way to read because the null byte could get lost.
  290.          So use EOFMODE and ask for the maximum permissible length.
  291.       */
  292.       Ser_Read->io_SerFlags |= SERF_EOFMODE;
  293.       Ser_Read->IOSer.io_Command = CMD_READ;
  294.       Ser_Read->IOSer.io_Length = (long) -l;
  295.       Ser_Read->IOSer.io_Data = (APTR) p;
  296.       BeginIO((struct IORequest *)Ser_Read);
  297.    }
  298.    else {
  299.       Ser_Read->IOSer.io_Command = CMD_READ;
  300.       Ser_Read->IOSer.io_Length = (long)l;
  301.       Ser_Read->IOSer.io_Data = (APTR) p;
  302.       BeginIO((struct IORequest *)Ser_Read);
  303.    }
  304.    i = rdwait();
  305.    if(l < 0) {
  306.       Ser_Read->io_SerFlags &= ~SERF_EOFMODE;
  307.    }
  308.    return(i == 0);
  309. }
  310. restart()
  311. {
  312.    rflag = 0;
  313.    Ser_Read->IOSer.io_Command = CMD_READ;
  314.    Ser_Read->IOSer.io_Length = 1L;
  315.    Ser_Read->IOSer.io_Data = (APTR) &rs_in[0];
  316.    BeginIO((struct IORequest *)Ser_Read);
  317. }
  318. rdwait()
  319. {
  320.    long waitbits;
  321.    register char ch;
  322.    extern unsigned char ichar;
  323.    extern struct IOStdReq *Con_Read;
  324.  
  325.    waitbits = windbit | readbit | keybit;
  326.    while(1)  {
  327.       getbits = Wait(waitbits);
  328.       if(windbit & getbits) {
  329.          while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  330.             class = NewMessage->Class;
  331.             code = NewMessage->Code;
  332.             switch( class ) {
  333.             case CLOSEWINDOW:
  334.                if(done_flag)done(1);
  335.                break;
  336.             default:
  337.                ReplyMsg((struct Message *) NewMessage );
  338.             }   /* end of switch (class) */
  339.          }
  340.       }
  341.       if(keybit & getbits) {
  342.          WaitIO((struct IORequest *)Con_Read);
  343.          ch = ichar;
  344.          Con_Read->io_Data = (APTR)&ichar;
  345.          Con_Read->io_Command = CMD_READ;
  346.          Con_Read->io_Length = 1;
  347.          SendIO((struct IORequest *)Con_Read);
  348.          if(ch == '\033') {
  349.             ttputs("rdwait\n");
  350.          }
  351.          if(ch == achar) {
  352.             port->mode = forced;
  353.             block_cancel = 1;
  354.             AbortIO((struct IORequest *)Ser_Read);
  355.             restart();
  356.             return(0);
  357.          }
  358.       }
  359.       if(readbit & getbits) {
  360.          WaitIO((struct IORequest *)Ser_Read);
  361.          return((short)Ser_Read->IOSer.io_Actual);
  362.       }
  363.    }
  364. }
  365.